#include"curve.h"
int main(int argc, char* argv[])
{
	int t;
	int num=10;
	char filename[9] = "some.dat";
    double *params;
    //输入要计算的曲线类型以及系数 
    while(1)
    {
    	printf("请输入函数类型t（取值为1、2、3）：");
         scanf("%d", &t);
    if (t == 1) {
        params = (double *)malloc(2 * sizeof(double));//开辟动态数组储存输入的一次函数参数
        //输入函数参数
        printf("请输入一次函数参数a：");
        scanf("%lf", &params[0]);
        printf("请输入一次函数参数b：");
        scanf("%lf", &params[1]);
        generate_dataset(filename,t,params[0],params[1],0,0,num);//生成数据集并存入"some.dat"文件
		break;
        
    } else if (t == 2) {
        params = (double *)malloc(3 * sizeof(double));//开辟动态数组储存输入的二次函数参数
        //输入函数参数
        printf("请输入二次函数参数a：");
        scanf("%lf", &params[0]);
        printf("请输入二次函数参数b：");
        scanf("%lf", &params[1]);
        printf("请输入二次函数参数c：");
        scanf("%lf", &params[2]);
        generate_dataset(filename,t,params[0],params[1],params[2],0,num);
        break;
    } else if (t == 3) {
        params = (double *)malloc(4 * sizeof(double));//开辟动态数组储存输入的三次函数参数
        //输入函数参数
        printf("请输入三次函数参数a：");
        scanf("%lf", &params[0]);
        printf("请输入三次函数参数b：");
        scanf("%lf", &params[1]);
        printf("请输入三次函数参数c：");
        scanf("%lf", &params[2]);
        printf("请输入三次函数参数d：");
        scanf("%lf", &params[3]);
        generate_dataset(filename,t,params[0],params[1],params[2],params[3],num);//生成数据集并存入"some.dat"文件
        break;
    } else {
        printf("输入的t值不合法，请重新输入\n");//判断函数类型是否出错
        system("pause");
		system("cls");
    }
	}
    free(params);
	
    char algorithm[3];
    int i=0;
    DataPoint *data = NULL;
    int num_data = readDataFromFile(filename, &data,num);//储存样本点数量并将样本点存入data数组
    if (num_data < 0) {
        return 1;
    }
	//输入选择拟合算法 
	FunctionParams params1;
    while(1)
	{
		printf("请输入拟合算法（ls表示最小二乘法，gd表示梯度下降法）：");
    	scanf("%s", algorithm);
    	
    	if (strcmp(algorithm, "ls") == 0) {
    		if(t==1){
        		linearRegression(data,  num_data, &params1.params[0], &params1.params[1]) ;//计算一次拟合函数的参数
        		printf("y = %.4lf + %.4lf * x\n", params1.params[0], params1.params[1]);//输出拟合函数表达式
			}
			else if(t==2)
			{
				quadraticRegression(data, num_data, &params1.params[0], &params1.params[1], &params1.params[2]);//计算二次拟合函数的参数
				printf("y = %.4lf + %.4lf * x + %.4lf * x^2\n", params1.params[0],params1.params[1], params1.params[2]);//输出拟合函数表达式
			}
			else if(t==3)
			{
    			cubicRegression(data, num_data, &params1.params[0], &params1.params[1], &params1.params[2],&params1.params[3]);//计算三次拟合函数的参数
    			printf("y = %.4lf + %.4lf * x + %.4lf * x^2 + %.4lf * x^3\n", params1.params[0], params1.params[1], params1.params[2],params1.params[3]);//输出拟合函数表达式
			}
        	break;
    	} 
		else if (strcmp(algorithm, "gd") == 0) {
            params1= gradientDescentFit(data,num_data,t);//计算拟合函数参数
            if(t==1){
        		printf("y = %.4lf + %.4lf * x\n", params1.params[0], params1.params [1]);//输出拟合函数表达式
			}
			else if(t==2)
			{
				printf("y = %.4lf + %.4lf * x + %.4lf * x^2\n", params1.params[0], params1.params[1],params1.params[2]);//输出拟合函数表达式
			}
			else if(t==3)
			{
    			printf("y = %.4lf + %.4lf * x + %.4lf * x^2 + %.4lf * x^3\n", params1.params[0], params1.params[1],params1.params[2],params1.params[3]);//输出拟合函数表达式
			}
    		printf("\n");
        	break;
    	}
		 else
		{
        	printf("无效的算法输入\n");
        	printf("请重新输入！\n"); 
        	free(data);
    	}
	 } 
	
    double rss = residualSumOfSquares(data,num_data,params1,t);//计算剩余平方和
    double r2= calculateRSquared(data,num_data,params1,t);//计算决定系数
    printf("拟合得到的参数: ");
    printf("\n剩余平方和（拟合度衡量指标）: %.6lf\n", rss);//输出剩余平方和
    printf("决定系数(衡量回归模型拟合优度):%.6lf",r2);//输出决定系数
    //开始可视化
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;
    if (!init_SDL(&window, &renderer)) {
        return 1;
    }
    
    SDL_SetRenderDrawColor(renderer, 255,255,255, 255);  // 设置背景色为白色
    SDL_RenderClear(renderer);
     draw_axes(renderer);
    draw_points(renderer, data, num_data);
    if(t==1)
    {
    	draw_linear_function(renderer, params1.params [1],params1.params [0]);//画出一次函数图像
	}
	else if(t==2)
	{
		draw_quadratic_function(renderer, params1.params [2],params1.params [1], params1.params [0]);//画出二次函数图像
	}
	else if(t==3)
	{
		draw_cubic_function(renderer, params1.params [3],params1.params [2],params1.params [1], params1.params [0]);//画出三次函数图像
	}
	SDL_RenderPresent(renderer);

    SDL_Delay(5000);  // 显示5秒，可根据需要调整

    close_SDL(window, renderer);
    free(data);//释放动态数组data
    return 0;
}

